﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Transactions;
using System.Web;
using log4net;
using log4net.Core;
using log4net.Layout;
using log4net.Layout.Pattern;

namespace CloudPms.Common.Log
{
    /// <summary>
    /// 日志填充
    /// <para>--------------------------</para>
    /// <para>@Author: cnalexi@gmail.com</para> 
    /// <para>@Create: 2012/3/17</para> 
    /// </summary>
    public class OperateLog
    {
        private static log4net.ILog _logger;// = log4net.LogManager.GetLogger("WynPmsLog");

        private static object lockThis = new object();

        private static void InitOperateLog()
        {
            string root = System.Web.Hosting.HostingEnvironment.MapPath("~") != null
                ? System.Web.Hosting.HostingEnvironment.MapPath("~") + @"\bin\"
                : string.Empty;

            if (string.IsNullOrEmpty(root))
            {
                root = (HttpContext.Current != null)
                              ? HttpContext.Current.Request.MapPath("~") + @"\bin\"
                              : string.Empty;
            }

            string path = root + @"log4net.config";

            //var assemblyPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(path));

            //log4net.Config.XmlConfigurator.Configure();

            _logger = LogManager.Exists("CommonLogger");
        }

        private static log4net.ILog Logger 
        {
            get
            {
                if(_logger==null)
                {
                    lock(lockThis)
                    {
                        if(_logger==null)
                        {
                            InitOperateLog();
                        }
                    }
                }
                return _logger;
            }
            
        }

        public static void DebugLog(LogMessage msg)
        {
            Logger.Debug(msg);
        }

        public static void DebugLog(LogMessage msg, Exception ex)
        {
            Logger.Debug(msg, ex);
        }

        public static void InfoLog(LogMessage msg)
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                //Logger.Info(msg);
                scope.Complete();
            }
        }

        public static void InfoLog(LogMessage msg, Exception ex)
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                //Logger.Info(msg);
                scope.Complete();
            }
            Logger.Error(msg.Message, ex);
        }

        public static void WarnLog(object msg)
        {
            Logger.Warn(msg);
        }

        public static void WarnLog(object msg, Exception ex)
        {
            Logger.Warn(msg, ex);
        }

        public static void ErrorLog(object msg)
        {
            Logger.Error(msg);
        }

        public static void ErrorLog(object msg, Exception ex)
        {
            Logger.Error(msg, ex);
        }

        public static void FatalLog(object msg)
        {
            Logger.Fatal(msg);
        }

        public static void FatalLog(object msg, Exception ex)
        {
            Logger.Fatal(msg, ex);
        }

    }

    public class CustomLayout : PatternLayout
    {
        public CustomLayout()
        {
            AddConverter("property", typeof(CustomPatternConverter));
        }
    }

    public class CustomPatternConverter : PatternLayoutConverter
    {

        protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            if (Option != null)
            {
                WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
            }
            else
            {
                WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
            }
        }

        private object LookupProperty(string property, LoggingEvent loggingEvent)
        {
            object propertyValue = string.Empty;

            PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);

            if (propertyInfo != null)
            {
                propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
            }
            return propertyValue;
        }
    }

    public class LogMessage
    {
        public LogMessage()
        {

        }

        public LogMessage(int categoryID, string employeeID,string employeeName, string relatedID, string originValue, string destinValue, bool isSuccess, string hotelID, string message)
        {
            CategoryID = categoryID;
            EmployeeID = employeeID;
            EmployeeName = employeeName;
            RelatedID = relatedID;
            Message = message;
            OriginValue = originValue;
            DestinValue = destinValue;
            IsSuccess = isSuccess;
            HotelID = hotelID;
        }
        

        public int CategoryID { get; set; }

        public string CategoryName
        {
            get { return LogCategory.GetCategoryName(CategoryID);}
        }

        public string EmployeeID { get; set; }

        public string EmployeeName { get; set; }

        public string RelatedID { get; set; }

        public string Message { get; set; }

        public string OriginValue { get; set; }

        public string DestinValue { get; set; }
        
        public bool IsSuccess { get; set; }

        public string HotelID { get; set; }

        public string ClientInfo
        {
            get
            {
                string client = string.Empty;

                if(System.Web.HttpContext.Current!=null)
                {
                    client = string.Format("{0}", HttpContext.Current.Request.UserHostAddress);
                }
                return client;
            }
        }

        public string HostInfo
        {
            get
            {
                string serverInfo = string.Empty;

                if(HttpContext.Current!=null)
                {
                    serverInfo = string.Format("{0}[{1}]",
                                               HttpContext.Current.Server.MachineName,
                                               HttpContext.Current.Request.ServerVariables.Get("Remote_Addr")
                                               );
                }
                return serverInfo;
            }
        }
        
    }
    
}
